package com.fh.web.realm;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cas.CasRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.web.subject.WebSubject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.fh.dao.PurRoleMapper;
import com.fh.dao.PurUser2RoleMapper;
import com.fh.dto.PurPurview;
import com.fh.dto.PurRole;
import com.fh.dto.PurUser2Role;
import com.fh.dto.SysLog;
import com.fh.dto.SysUser;
import com.fh.web.common.SysLogParam;
import com.fh.web.constants.GlobalConstants;
import com.fh.web.service.CustomService;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

/**
 * 用户授权信息域
 * 
 * @author yub
 * 
 */
public class UserRealm extends CasRealm {
	private final Logger LOGGER = LoggerFactory.getLogger(getClass());

	@Resource
	private CustomService customService;
	@Resource
	private PurRoleMapper purRoleMapper;
	@Resource
	private PurUser2RoleMapper userRoleDtoMapper;
	
	protected final Map<String, SimpleAuthorizationInfo> roles = new ConcurrentHashMap<String, SimpleAuthorizationInfo>();
	
	@Override
	@SuppressWarnings("unchecked")
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		String account = (String) principals.getPrimaryPrincipal();
		Map<String, Object> info = (Map<String, Object>)principals.asList().get(1);
		String userCode = info.get("userCode")==null ?  "" : info.get("userCode").toString();
		String userName = info.get("userName")==null ?  "" : info.get("userName").toString();
		String userTypeId = info.get("userTypeId")==null ?  "" : info.get("userTypeId").toString();
		if (account != null && !"".equals(account)) {
			try {
				SysUser sysUser = new SysUser();
				sysUser.setUserId(Long.valueOf(account));
				sysUser.setUserCode(userCode);
				sysUser.setUserTypeId(Long.valueOf(userTypeId));
				sysUser.setUserName(URLDecoder.decode(userName, "UTF-8"));
				//角色
				Example example = new Example(PurUser2Role.class);
				Criteria criteria = example.createCriteria();
				criteria.andEqualTo("userId", account);
				List<PurUser2Role> userRoleList = userRoleDtoMapper.selectByExample(example);
				if (userRoleList != null && userRoleList.size()>0) {
					for (int i = 0; i < userRoleList.size(); i++) {
						PurUser2Role purUser2Role = userRoleList.get(i);
						PurRole purRole = purRoleMapper.selectByPrimaryKey(purUser2Role.getRoId());
						authorizationInfo.addRole(purRole.getToName());
					}
					//权限点
					List<PurPurview> purviewList = customService.getUserPurview(sysUser);
					if (purviewList != null && purviewList.size()>0) {
						for (int i = 0; i < purviewList.size(); i++) {
							PurPurview purPurview = purviewList.get(i);
							authorizationInfo.addStringPermission(purPurview.getPurCode());
						}
					}
					//LOGGER.info(authorizationInfo.getRoles().toString());
					//LOGGER.info(authorizationInfo.getStringPermissions().toString());
				}
				roles.put(account, authorizationInfo);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return authorizationInfo;
	}
	
	@Override
	@SuppressWarnings("unchecked")
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token){
		AuthenticationInfo authc = super.doGetAuthenticationInfo(token);
		String account = (String) authc.getPrincipals().getPrimaryPrincipal();
		Map<String, Object> info = (Map<String, Object>)authc.getPrincipals().asList().get(1);
		//String id = info.get("id").toString();
		String userCode = info.get("userCode")==null ?  "" : info.get("userCode").toString();
		String userName = info.get("userName")==null ?  "" : info.get("userName").toString();
		//用户类型 1：学生 2：老师
		String userTypeId = info.get("userTypeId")==null ?  "" : info.get("userTypeId").toString();
		SysUser sysUser = new SysUser();
		try {
			sysUser.setUserId(Long.valueOf(account));
			sysUser.setUserCode(userCode);
			sysUser.setUserTypeId(Long.valueOf(userTypeId));
			sysUser.setUserName(URLDecoder.decode(userName, "UTF-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		Session session = SecurityUtils.getSubject().getSession();
		ServletRequest request = ((WebSubject)SecurityUtils.getSubject()).getServletRequest();   
		HttpSession httpSession = ((HttpServletRequest)request).getSession(); 
		//用户Session
		httpSession.setAttribute(GlobalConstants.SYS_USER, sysUser);
		//日志Session
		SysLog sysLog = new SysLog();
		sysLog.setOptDesc(SysLogParam.USER_LOGIN.getDesc());
		sysLog.setIp(session.getHost());
		sysLog.setOptType(SysLogParam.USER_LOGIN.getCode());
		sysLog.setTime(session.getStartTimestamp());
		sysLog.setUserId(sysUser.getUserId());
		sysLog.setUserName(sysUser.getUserName());
		sysLog.setUserTypeId(sysUser.getUserTypeId());
		httpSession.setAttribute(GlobalConstants.SYS_LOG_LOGIN, sysLog);
		
		//LOGGER.debug("httpSession.getServletContext():"+httpSession.getServletContext());  
		//WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(httpSession.getServletContext());  
		return authc;
		
	}
	
	public void clearCached() {
		PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
		super.clearCache(principals);
	}

}
